<template>
  <main-page title="表单字段管理">
    <div class="form-designer">
      <div class="filter">
        <span class="filter-item">
          <span class="label">字段标题：</span>
          <el-input v-model="propertyName" style="width: 200px" @keyup.enter.native="searchClick"></el-input>
        </span>
        <span class="filter-item">
          <span class="label">业务模块：</span>
          <el-select v-model="businessModule" style="width: 258px" multiple clearable placeholder="请选择">
            <el-option
              v-for="item in businessModuleList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </span>
        <el-button type="primary" @click="searchClick">查询</el-button>
        <el-button type="text" @click="resetClick">重置</el-button>
        <el-button
          v-permission="['systemConfig:formField:add']"
          type="primary"
          style="margin-left: auto"
          @click="addClick"
        >
          新增
        </el-button>
      </div>
      <div class="content">
        <FormTable :table-data="tableData" :table-label="tableLabel">
          <template #operation="slotProps">
            <!-- <el-tooltip
              class="item"
              effect="dark"
              :disabled="!slotProps.row.isUsed"
              content="字段已被使用，不可编辑！"
              placement="top"
            >
              <span> -->
            <el-button
              v-permission="['systemConfig:formField:edit']"
              type="text"
              class="operationBtn"
              @click="editClick(slotProps.row)"
            >
              编辑
            </el-button>
            <!-- </span>
            </el-tooltip> -->

            <el-tooltip
              v-permission="['systemConfig:formField:del']"
              class="item"
              effect="dark"
              :disabled="!slotProps.row.isUsed"
              content="字段已被使用，不可删除！"
              placement="top"
            >
              <span>
                <el-popconfirm
                  confirm-button-text="删除"
                  cancel-button-text="取消"
                  icon="el-icon-info"
                  :disabled="slotProps.row.isUsed"
                  icon-color="red"
                  :title="`确定删除${slotProps.row.propertyName}吗？`"
                  @confirm="delForm(slotProps.row.propertyDefinitionId)"
                >
                  <el-button slot="reference" :disabled="slotProps.row.isUsed" type="text" class="operationBtn">
                    删除
                  </el-button>
                </el-popconfirm>
              </span>
            </el-tooltip>
          </template>
        </FormTable>
      </div>
      <pagination
        style="height: 50px"
        :search-data="searchData"
        :table-total-size="tableTotalSize"
        @getTableData="getFormPropertyDefinitionPageList"
      />
    </div>

    <el-dialog
      :visible.sync="dialogVisibel"
      width="480px"
      :title="dialogTitle"
      destory-on-close
      @open="dialogOpen"
      @closed="dialogClose"
    >
      <div>
        <el-form
          v-if="dialogVisibel"
          ref="form"
          label-position="right"
          label-width="80px"
          size="small"
          :rules="rules"
          :model="formData"
        >
          <el-form-item label="字段" prop="propertyKey">
            <el-tooltip
              class="item"
              :disabled="(dialogTitle === '修改字段' && !row.isUsed) || dialogTitle === '新增字段'"
              content="字段已被使用，不可编辑!"
              placement="top"
            >
              <span>
                <el-input
                  v-model.trim="formData.propertyKey"
                  :disabled="row.isUsed"
                  class="show-word-limit"
                  maxlength="40"
                  show-word-limit
                ></el-input>
              </span>
            </el-tooltip>
          </el-form-item>
          <el-form-item label="字段标题" prop="propertyName">
            <el-input
              v-model.trim="formData.propertyName"
              class="show-word-limit"
              maxlength="40"
              show-word-limit
            ></el-input>
          </el-form-item>
          <el-form-item label="组件类型" prop="componentType">
            <el-tooltip
              class="item"
              :disabled="(dialogTitle === '修改字段' && !row.isUsed) || dialogTitle === '新增字段'"
              content="字段已被使用，不可编辑!"
              placement="top"
            >
              <span>
                <el-select
                  v-model="formData.componentType"
                  :disabled="row.isUsed"
                  placeholder="请选择"
                  @change="componentTypeChange"
                >
                  <el-option
                    v-for="item in componentList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </span>
            </el-tooltip>
          </el-form-item>
          <el-form-item v-if="formData.componentType" label="字段类型" prop="valueType">
            <el-tooltip
              class="item"
              :disabled="(dialogTitle === '修改字段' && !row.isUsed) || dialogTitle === '新增字段'"
              content="字段已被使用，不可编辑!"
              placement="top"
            >
              <span>
                <el-select
                  v-model="formData.valueType"
                  :disabled="row.isUsed"
                  placeholder="请选择"
                  @change="formData.options = []"
                >
                  <el-option
                    v-for="item in valueTypeList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </span>
            </el-tooltip>
          </el-form-item>
          <el-form-item v-if="[5, 7, 8].includes(formData.componentType)" label="选项" prop="options">
            <div v-for="(item, index) in formData.options" :key="index" class="option-item">
              <div class="select-line-icon">
                <i class="el-icon-s-operation" />
              </div>
              <el-input
                v-model="item.label"
                :disabled="row.isUsed"
                placeholder="选项名"
                size="small"
                maxlength="200"
              />
              <el-input
                placeholder="选项值"
                :disabled="row.isUsed"
                size="small"
                :value="item.value"
                maxlength="200"
                @input="setOptionValue(item, $event)"
              />
              <div
                v-if="!row.isUsed"
                class="close-btn select-line-icon"
                @click="formData.options.splice(index, 1)"
              >
                <i class="el-icon-remove-outline" />
              </div>
            </div>
            <div v-if="!row.isUsed" style="margin-left: 20px">
              <el-button
                style="padding-bottom: 0"
                icon="el-icon-circle-plus-outline"
                type="text"
                @click="addSelectItem"
              >
                添加选项
              </el-button>
            </div>
          </el-form-item>
          <el-form-item label="业务模块" prop="businessModule">
            <el-tooltip
              class="item"
              :disabled="(dialogTitle === '修改字段' && !row.isUsed) || dialogTitle === '新增字段'"
              content="字段已被使用，不可编辑!"
              placement="top"
            >
              <span>
                <el-select v-model="formData.businessModule" :disabled="row.isUsed" placeholder="请选择">
                  <el-option
                    v-for="item in businessModuleList"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </span>
            </el-tooltip>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div style="text-align: center">
          <el-button @click="dialogVisibel = false">取消</el-button>
          <el-button type="primary" @click="submitForm">确认</el-button>
        </div>
      </template>
    </el-dialog>
  </main-page>
</template>

<script>
import _ from 'lodash'
import MainPage from '@/components/main-page/index.vue'
import FormTable from '@/components/form-table/index.vue'
import pagination from '@/components/Table/pagination.vue'
import {
  getFormPropertyDefinitionPageList,
  addFormPropertyDefinition,
  editFormPropertyDefinition,
  batchDeleteFormPropertyDefinition
} from '@/api/system-config.js'
import defaultSettings from '@/settings'
import { generateUUID, postMessage, receivedMessage } from '@/utils/index'

export default {
  name: 'FieldManagement',
  components: { MainPage, FormTable, pagination },

  data() {
    return {
      propertyName: '',
      businessModule: [],
      searchData: { currentPage: 1, pageSize: 10 },
      tableTotalSize: 0,
      dialogVisibel: false,
      formData: {
        componentType: '',
        propertyKey: '',
        propertyName: '',
        businessModule: 1,
        valueType: '',
        options: []
      },
      classificationList: [],
      tableData: [],
      dialogTitle: '',
      isLoading: false,
      businessModuleList: [
        {
          label: '被控芯片参数模块',
          value: 1
        }
      ],
      rules: {
        componentType: [{ required: true, message: '请选择组件类型', trigger: 'change' }],
        propertyKey: [
          { required: true, message: '请输入字段', trigger: 'blur' },
          {
            pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/,
            message: '字段以字母开头，并且由数字字母下划线组成',
            trigger: 'blur'
          }
        ],
        propertyName: [{ required: true, message: '请输入字段标题', trigger: 'blur' }],
        valueType: [{ required: true, message: '请选择字段类型', trigger: 'blur' }],
        businessModule: [{ required: true, message: '请选择业务模块', trigger: 'blur' }],
        options: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (!value?.length) {
                callback('选项不能为空')
              } else {
                if (!value.every(({ label }) => label)) {
                  callback('选项名不能为空')
                } else {
                  callback()
                }
              }
            },
            trigger: 'blur'
          }
        ]
      },
      tableLabel: [
        {
          prop: 'No',
          label: '序号',
          width: 60
        },
        {
          prop: 'propertyName',
          label: '字段标题'
        },
        {
          prop: 'propertyKey',
          label: '字段'
        },
        {
          prop: 'valueType',
          label: '字段类型',
          valueFormat: (scope, label) =>
            this.fieldTypeList.filter(({ value }) => scope.row[label.prop] === value)?.[0]?.label ?? ''
        },
        {
          prop: 'componentType',
          label: '组件类型',
          valueFormat: (scope, label) =>
            this.componentList.filter(({ value }) => scope.row[label.prop] === value)?.[0]?.label ?? ''
        },
        {
          prop: 'businessModule',
          label: '业务模块',
          valueFormat: (scope, label) =>
            this.businessModuleList.filter(({ value }) => scope.row[label.prop] === value)?.[0]?.label ?? ''
        },
        {
          prop: 'operation',
          label: '操作',
          type: 'slot'
        }
      ],
      componentList: [
        {
          label: '单行文本',
          value: 1,
          componenValueTypeList: [1]
        },
        {
          label: '多行文本',
          value: 2,
          componenValueTypeList: [1]
        },
        {
          label: '密码',
          value: 3,
          componenValueTypeList: [1]
        },
        {
          label: '计数器',
          value: 4,
          componenValueTypeList: [2]
        },
        {
          label: '下拉选择',
          value: 5,
          componenValueTypeList: [1, 3]
        },
        {
          label: '级联选择',
          value: 6,
          componenValueTypeList: [3]
        },
        {
          label: '单选框组',
          value: 7,
          componenValueTypeList: [1]
        },
        {
          label: '多选框组',
          value: 8,
          componenValueTypeList: [3]
        },
        {
          label: '开关',
          value: 9,
          componenValueTypeList: [4]
        },
        {
          label: '滑块',
          value: 10,
          componenValueTypeList: [2]
        },
        {
          label: '时间选择',
          value: 11,
          componenValueTypeList: [1]
        },
        {
          label: '时间范围',
          value: 12,
          componenValueTypeList: [3]
        },
        {
          label: '日期选择',
          value: 13,
          componenValueTypeList: [1]
        },
        {
          label: '日期范围',
          value: 14,
          componenValueTypeList: [3]
        },
        {
          label: '评分',
          value: 15,
          componenValueTypeList: [2]
        },
        {
          label: '颜色选择',
          value: 16,
          componenValueTypeList: [1]
        },
        {
          label: '时间计算',
          value: 17,
          componenValueTypeList: [2]
        },
        {
          label: '数字',
          value: 18,
          componenValueTypeList: [2]
        },
        {
          label: '文件上传',
          value: 19,
          componenValueTypeList: [1]
        }
      ],
      fieldTypeList: [
        {
          label: '字符串',
          value: 1
        },
        {
          label: '数字',
          value: 2
        },
        {
          label: '数组',
          value: 3
        },
        {
          label: '布尔',
          value: 4
        }
      ],
      valueTypeList: [],
      getFormPropertyDefinitionPageListRequestId: generateUUID(),
      addFormPropertyDefinitionRequestId: generateUUID(),
      editFormPropertyDefinitionRequestId: generateUUID(),
      batchDeleteFormPropertyDefinitionRequestId: generateUUID()
    }
  },
  created() {
    this.getFormPropertyDefinitionPageList()
  },
  mounted() {
    receivedMessage(this.dataHandle)
  },
  methods: {
    dataHandle(result) {
      let self = this
      let e = defaultSettings.isWPF ? result : { data: JSON.parse(result) }
      if (e.data.webInfo.requestId === self.getFormPropertyDefinitionPageListRequestId) {
        let res = e.data.response
        self.tableData = res.data.map((item, index) => ({
          ...item,
          No: self.searchData.pageSize * (self.searchData.currentPage - 1) + index + 1
        }))
        self.tableTotalSize = res.total_count
        self.isLoading = false
      } else if (e.data.webInfo.requestId === self.addFormPropertyDefinitionRequestId) {
        let res = e.data.response
        if (res.success) {
          self.$message.success('字段增加成功！')
          self.dialogVisibel = false
          self.searchData.currentPage = 1
          self.getFormPropertyDefinitionPageList()
        } else {
          self.$message.error(res.message)
        }
      } else if (e.data.webInfo.requestId === self.editFormPropertyDefinitionRequestId) {
        let res = e.data.response
        if (res.success) {
          self.$message.success('字段修改成功！')
          self.dialogVisibel = false
          self.getFormPropertyDefinitionPageList()
        } else {
          self.$message.error(res.message)
        }
      } else if (e.data.webInfo.requestId === self.batchDeleteFormPropertyDefinitionRequestId) {
        let res = e.data.response
        if (res.success) {
          self.$message.success('字段删除成功！')
          if (self.tableData.length <= 1) {
            self.searchData.currentPage = 1
          }
          self.getFormPropertyDefinitionPageList()
        } else {
          self.$message.error(res.message)
        }
      }
    },
    delForm(propertyDefinitionId) {
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.batchDeleteFormPropertyDefinitionRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formPropertyDefinition/deleteFormPropertyDefinition',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: { propertyDefinitionId: propertyDefinitionId },
          WebInfo: {
            requestId: this.batchDeleteFormPropertyDefinitionRequestId
          }
        }
        postMessage(message)
      } else {
        batchDeleteFormPropertyDefinition({ propertyDefinitionId: propertyDefinitionId }).then(() => {
          this.$message.success('字段删除成功！')
          if (this.tableData.length <= 1) {
            this.searchData.currentPage = 1
          }
          this.getFormPropertyDefinitionPageList()
        })
      }
    },
    addSelectItem() {
      this.formData?.options?.push({
        label: '',
        value: ''
      })
    },
    setOptionValue(item, val) {
      function isNumberStr(str) {
        return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
      }
      if (this.formData.valueType === 3) {
        item.value = val
        return
      }
      item.value = isNumberStr(val) ? +val : val
    },
    componentTypeChange(value) {
      let componenValueTypeList = []
      this.componentList.forEach((item) => {
        if (item.value === value) {
          componenValueTypeList = item.componenValueTypeList
          this.formData.valueType = componenValueTypeList[0]
        }
      })
      this.valueTypeList = this.fieldTypeList.filter(({ value }) => componenValueTypeList.includes(value))
    },
    getFormPropertyDefinitionPageList() {
      this.isLoading = true
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.getFormPropertyDefinitionPageListRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/formPropertyDefinition/getFormPropertyDefinitionPageList',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: {
            ...this.searchData,
            params: { propertyName: this.propertyName, businessModule: this.businessModule }
          },
          WebInfo: {
            requestId: this.getFormPropertyDefinitionPageListRequestId
          }
        }
        postMessage(message)
      } else {
        getFormPropertyDefinitionPageList({
          ...this.searchData,
          params: { propertyName: this.propertyName, businessModule: this.businessModule }
        })
          .then((res) => {
            this.tableData = res.data.map((item, index) => ({
              ...item,
              No: this.searchData.pageSize * (this.searchData.currentPage - 1) + index + 1
            }))
            this.tableTotalSize = res.total_count
          })
          .finally(() => {
            this.isLoading = false
          })
      }
    },
    addClick() {
      this.formData = {
        componentType: '',
        propertyKey: '',
        propertyName: '',
        businessModule: 1,
        valueType: '',
        options: []
      }
      this.row = this.formData
      this.dialogTitle = '新增字段'
      this.dialogVisibel = true
    },
    submitForm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.formData.businessModule === 1 && this.formData.componentType === 1) {
            this.formData.regList = [
              {
                pattern: '/^(-?\\d+)(\\.\\d+)?$/',
                message: '请输入正确数字'
              }
            ]
          }

          if (this.dialogTitle === '新增字段') {
            if (defaultSettings.isWPF || defaultSettings.isCEF) {
              this.addFormPropertyDefinitionRequestId = generateUUID()
              let message = {
                RequestUrl: process.env.VUE_APP_URL + '/formPropertyDefinition/addFormPropertyDefinition',
                RequestMethod: 'POST',
                Headers: {
                  contentType: 'application/json'
                },
                QueryParameter: {},
                RequestBody: this.formData,
                WebInfo: {
                  requestId: this.addFormPropertyDefinitionRequestId
                }
              }
              postMessage(message)
            } else {
              addFormPropertyDefinition(this.formData).then((res) => {
                this.$message.success('字段增加成功！')
                this.dialogVisibel = false
                this.searchData.currentPage = 1
                this.getFormPropertyDefinitionPageList()
              })
            }
          } else {
            if (defaultSettings.isWPF || defaultSettings.isCEF) {
              this.editFormPropertyDefinitionRequestId = generateUUID()
              let message = {
                RequestUrl: process.env.VUE_APP_URL + '/formPropertyDefinition/editFormPropertyDefinition',
                RequestMethod: 'POST',
                Headers: {
                  contentType: 'application/json'
                },
                QueryParameter: {},
                RequestBody: this.formData,
                WebInfo: {
                  requestId: this.editFormPropertyDefinitionRequestId
                }
              }
              postMessage(message)
            } else {
              editFormPropertyDefinition(this.formData).then(() => {
                this.$message.success('字段修改成功！')
                this.dialogVisibel = false
                this.getFormPropertyDefinitionPageList()
              })
            }
          }
        }
      })
    },
    resetClick() {
      this.propertyName = ''
      this.businessModule = []
      this.getFormPropertyDefinitionPageList()
    },
    searchClick() {
      this.searchData.currentPage = 1
      this.getFormPropertyDefinitionPageList()
    },
    dialogOpen() {},
    dialogClose() {
      this.formData = { propertyName: '', businessModule: 1 }
    },
    editClick(row) {
      this.row = row
      this.formData = _.cloneDeep(row)
      const componentType = this.formData.componentType
      let componenValueTypeList = []
      this.componentList.forEach((item) => {
        if (item.value === componentType) {
          componenValueTypeList = item.componenValueTypeList
        }
      })
      this.valueTypeList = this.fieldTypeList.filter(({ value }) => componenValueTypeList.includes(value))
      this.dialogTitle = '修改字段'
      this.dialogVisibel = true
    }
  }
}
</script>

<style lang="scss" scoped>
.filter {
  display: flex;
  padding-bottom: 20px;
  align-items: center;
  .filter-item {
    margin-right: 12px;
  }
}
.operationBtn {
  padding: 10px 10px;
}
.el-form-item {
  .el-tree-select ::v-deep.el-select,
  .el-select,
  .el-input {
    width: 320px;
  }
}
.form-designer {
  height: 100%;
  display: flex;
  flex-direction: column;
  .content {
    min-height: 200px;
    flex: 1;
  }
}
.option-item {
  display: flex;
  align-items: center;
  > .select-line-icon {
    font-size: 20px;
    padding: 0 5px;
  }
  > .close-btn {
    color: red;
    cursor: pointer;
  }
}
</style>
